{% extends 'layout/base.twig' %}

{% block head %}
<link href="{{ static('css/d3.flameGraph.css') }}" rel="stylesheet" media="screen">
{% endblock %}

{% block title %}
- Flamegraph - {{ profile.meta.url }} - {{ profile.meta('SERVER.REQUEST_TIME')|date(date_format) }}
{% endblock %}

{% block content %}
<div class="row-fluid">
    <a class="back-link" href="{{ url('run.view', {'id': profile.id|trim}) }}">&laquo; Back to run</a>
    <h1>Flamegraph for {{ profile.meta.url }}</h1>
    <h4>{{ profile.meta('SERVER.REQUEST_TIME')|date(date_format) }}</h4>
</div>

<div class="row-fluid">
<form class="search-form form-inline" id="form">
	<div class="control-group span8">
		<a class="btn" id="flamegraph-reset">Reset zoom</a>
	</div>
	<div class="control-group span4 text-right">
		<input type="text" class="form-control" id="term">
		<button class="btn btn-primary" id="flamegraph-search">Search</button>
		<button class="btn" id="flamegraph-clear">Clear</button>
	</div>
</form>
</div>

<div class="row-fluid">
    <div id="chart"></div>
</div>

<div class="alert alert-info">
    Flamegraphs help visualize where long running methods are, as well as methods
    that have deep call stacks.
</div>
{% endblock %}


{% block jsfoot %}
<script src="{{ static('js/d3-tip-index.js') }}"></script>
<script src="{{ static('js/d3.flameGraph.js') }}"></script>
<script type="text/javascript">

var width = parseInt($('#chart').css('width'), 10);
var cellHeight = 18;

var flameGraph = d3.flameGraph()
    .height(540)
    .width(width)
    .cellHeight(cellHeight)
    .transitionDuration(750)
    .transitionEase('cubic-in-out')
    .sort(true);

var tip = d3.tip()
    .direction("s")
    .offset([8, 0])
    .attr('class', 'd3-flame-graph-tip')
    .html(function(d) {
        var units = 'µs';
        return d.name + " &mdash; " + Xhgui.formatNumber(d.value) + units + ' (' + Math.round(100 * d.dx, 3) + '%)';
    });

flameGraph.tooltip(tip);

d3.json("{{ url('run.flamegraph.data', {id: profile.id|trim }) }}", function(error, data) {
    if (error) {
        return console.warn(error);
    }

    flameGraph.height(getDepth(data.data) * cellHeight);

    flameGraph.sort(function (a, b) {
        return data.sort[a.name] - data.sort[b.name];
    });

    d3.select("#chart")
        .datum(data.data)
        .call(flameGraph);
});

$(document).ready(function(){
    $("form").submit(function(event){
        event.preventDefault();
        flameGraph.search($('#term').val());
    });
});

$('#flamegraph-search').on('click', function () {
    flameGraph.search($("#term").val());
});

$('#flamegraph-clear').on('click', function() {
    $('#term').val('');
    flameGraph.clear();
});

$('#flamegraph-reset').on('click', function () {
    flameGraph.resetZoom();
});

function getDepth (obj) {
    var depth = 0;
    if (obj.children) {
        obj.children.forEach(function (d) {
            var tmpDepth = getDepth(d)
            if (tmpDepth > depth) {
                depth = tmpDepth
            }
        })
    }
    return 1 + depth
}

</script>
{% endblock %}
